home *** CD-ROM | disk | FTP | other *** search
- /*************************** driver.c **************************************
-
- Purpose: Test driver program for boolean operations code.
-
- Provenance: Written and tested by S. Wartik, April 1991.
-
- Notes: This module contains a main program and accompanying
- subroutines that, when compiled, exercise every function
- of the boolean operations module. The testing is purely
- in terms of the external interface that the boolean
- operations module presents. That is, the effects of
- constructor functions are examined through the projector
- functions. This makes the code (almost) implementation-
- independent. For this reason, it may be used (with slight
- modifications, controlled through #ifdef's) to test both
- the bit-vector and the hashing implementations.
-
- Usage for the bit-vector version is:
-
- driver lower-bound upper-bound
-
- where the bounds specify the legal domain of the set. In
- the current implementation, abs(upper-bound - lower-bound)
- must be less than 256.
-
- **/
-
- #include <stdio.h>
-
- # include "hash.h"
-
- #define N_SETS 3
-
- #define MIN_ELEMENTS 5 /* Make the tests "interesting". */
- /* Require at least 5 elements. */
- int hash(key) /* Define the hashing function */
- elementType key; /* as the sum of the squares of */
- { /* each bit's magnitude, base 3. */
- int i;
- int threePower;
- int sum;
-
- threePower = 1;
- sum = 0;
- for ( i = 0; i < 8*sizeof(elementType); i++ ) {
- register int bitValue;
- bitValue = (key & 01)*threePower;
- bitValue *= bitValue;
- sum += bitValue;
- threePower *= 3;
- }
-
- return sum;
- }
-
- boolean compare(v1, v2)
- elementType v1, v2;
- {
- return v1 == v2;
- }
-
-
- void Exit_If_Error_On();
- void Exit_Indicating_Failed_Op();
-
-
- void Test_Set_Operators(); /* The main routine is implemented */
- void Test_Union_Operators(); /* as a series of calls to several */
- void Test_Intersection_Operators(); /* procedures, each of which tests */
- void Test_Subtraction_Operators(); /* a particular aspect of the */
- void Test_Copy(); /* module. */
- void Test_Iterate();
-
- boolean Iterator();
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- set s[N_SETS];
- int lower, upper;
- int number_of_buckets;
- int i;
-
- if ( argc != 4 ) {
- printf("Usage: %s lower-bound upper-bound number-of-buckets\n", argv[0]);
- exit(1);
- }
-
- lower = atoi(argv[1]);
- upper = atoi(argv[2]);
- if ( upper < lower+MIN_ELEMENTS ) {
- printf("Please specify a set that can contain at least %d elements.\n",
- MIN_ELEMENTS);
- exit(1);
- }
- if ( (number_of_buckets = atoi(argv[3])) <= MIN_ELEMENTS ) {
- printf("The 1st argument must be an integer >= %d.\n",
- MIN_ELEMENTS);
- exit(1);
- }
-
-
- for ( i = 0; i < N_SETS; i++ ) { /* Test creation. */
- Create(number_of_buckets, hash, compare, &s[i]);
- Exit_If_Error_On("Create");
- }
- fputs("Creation works.\n", stdout);
-
- for ( i = 0; i < 2; i++ ) { /* Test clearing sets. */
- Clear(&s[i]);
- Exit_If_Error_On("Clear");
- if ( Empty(&s[i]) )
- Exit_If_Error_On("Empty");
- else Exit_Indicating_Failed_Op("Empty");
- }
- fputs("Clearing works.\n", stdout);
-
- Test_Set_Operators(s, lower, upper);
- fputs("Basic operators works.\n", stdout);
- Test_Union_Operators(s, lower, upper);
- fputs("Union works.\n", stdout);
- Test_Intersection_Operators(s, lower, upper);
- fputs("Intersection works.\n", stdout);
- Test_Subtraction_Operators(s, lower, upper);
- fputs("Subtraction works.\n", stdout);
- Test_Copy(s, lower, upper);
- fputs("Copying works.\n", stdout);
- Test_Iterate(s, lower, upper);
- fputs("Iterating works.\n", stdout);
-
- fputs("\nThe implementation passes.\n", stdout);
- exit(0);
- }
-
- void Test_Set_Operators(s, lower, upper)
- set s[];
- int lower, upper;
- {
- int i;
-
- for ( i = lower; i <= upper; i++ ) { /* Test insertion of all */
- Insert(&s[0], i); /* valid elements for a */
- Exit_If_Error_On("Insert"); /* set that doesn't already */
- if ( Member(&s[0], i) ) /* contain them. */
- Exit_If_Error_On("Member");
- else Exit_Indicating_Failed_Op("Member");
- }
-
- for ( i = lower; i <= upper; i++ ) { /* Test insertion of all */
- Insert(&s[0], i); /* valid elements for a */
- Exit_If_Error_On("Insert"); /* set that already has */
- if ( Member(&s[0], i) ) /* them. */
- Exit_If_Error_On("Member");
- else Exit_Indicating_Failed_Op("Member");
- }
-
- for ( i = lower; i <= upper; i++ ) { /* Test deletion of all */
- Delete(&s[0], i); /* valid elements when */
- Exit_If_Error_On("Delete"); /* the set already has */
- if ( ! Member(&s[0], i) ) /* them. */
- Exit_If_Error_On("Delete");
- else Exit_Indicating_Failed_Op("Member");
- }
-
- for ( i = lower; i <= upper; i++ ) { /* Test deletion of all */
- Delete(&s[0], i); /* valid elements when */
- Exit_If_Error_On("Delete"); /* the set doesn't have */
- if ( ! Member(&s[0], i) ) /* them. */
- Exit_If_Error_On("Delete");
- else Exit_Indicating_Failed_Op("Member");
- }
- }
-
- void Test_Union_Operators(s, lower, upper)
- set s[];
- int lower, upper;
- {
- int i;
-
- Insert(&s[0], lower); /* Test union of a set */
- Exit_If_Error_On("Insert"); /* with an empty set. */
- Unite(&s[0], &s[1], &s[2]); /* s2 <- {lower}U{} */
- Exit_If_Error_On("Unite");
- if ( Member(&s[2], lower) )
- Exit_If_Error_On("Member");
- else Exit_Indicating_Failed_Op("Member|Unite");
- for ( i = lower+1; i <= upper; i++ )
- if ( Member(&s[2], i) )
- Exit_Indicating_Failed_Op("Member|Unite");
- else Exit_If_Error_On("Member");
-
- Insert(&s[1], lower+1); /* Test union of two non- */
- Exit_If_Error_On("Insert"); /* empty, non-intersecting */
- Unite(&s[0], &s[1], &s[2]); /* sets. */
- Exit_If_Error_On("Unite"); /* s2 <- {lower}U{lower+1} */
- if ( Member(&s[2], lower) && Member(&s[2], lower+1) )
- Exit_If_Error_On("Member");
- else Exit_Indicating_Failed_Op("Member|Unite");
- for ( i = lower+2; i <= upper; i++ )
- if ( Member(&s[2], i) )
- Exit_Indicating_Failed_Op("Member|Unite");
- else Exit_If_Error_On("Member");
-
- /* Test union of two non-empty, */
- Insert(&s[0], lower+1); /* intersecting sets. */
- Exit_If_Error_On("Insert"); /* s2 <- {lower,lower+1} U */
- Unite(&s[0], &s[1], &s[2]); /* {lower+1} */
- Exit_If_Error_On("Unite");
- if ( Member(&s[2], lower) && Member(&s[2], lower+1) )
- Exit_If_Error_On("Member");
- else Exit_Indicating_Failed_Op("Member|Unite");
- for ( i = lower+2; i <= upper; i++ )
- if ( Member(&s[2], i) )
- Exit_Indicating_Failed_Op("Member|Unite");
- else Exit_If_Error_On("Member");
- }
-
- void Test_Intersection_Operators(s, lower, upper)
- set s[];
- int lower, upper;
- {
- int i;
-
- Clear(&s[0]);
- Clear(&s[1]);
-
- Insert(&s[0], lower); /* Test intersection of a */
- Exit_If_Error_On("Insert"); /* set with an empty set. */
- Intersect(&s[0], &s[1], &s[2]); /* s2 <- {lower}^{} */
- Exit_If_Error_On("Intersect");
- for ( i = lower; i <= upper; i++ )
- if ( Member(&s[2], i) )
- Exit_Indicating_Failed_Op("Member|Intersect");
- else Exit_If_Error_On("Member");
-
- Insert(&s[0], lower); /* Test intersection of two */
- Exit_If_Error_On("Insert"); /* non-empty, non-intersecting */
- Insert(&s[1], lower+1); /* sets. */
- Exit_If_Error_On("Insert"); /* s2 <- {lower}^{lower+1} */
- Intersect(&s[0], &s[1], &s[2]);
- Exit_If_Error_On("Intersect");
- for ( i = lower; i <= upper; i++ )
- if ( Member(&s[2], i) )
- Exit_Indicating_Failed_Op("Member|Intersect");
- else Exit_If_Error_On("Member");
-
- Insert(&s[0], lower); /* Test intersection of two non- */
- Exit_If_Error_On("Insert"); /* non-empty, intersecting sets. */
- Insert(&s[0], lower+1); /* s2 <- {lower,lower+1}^ */
- Exit_If_Error_On("Insert"); /* {lower,lower+2} */
- Clear(&s[1]);
- Insert(&s[1], lower);
- Exit_If_Error_On("Insert");
- Insert(&s[1], lower+2);
- Exit_If_Error_On("Insert");
- Intersect(&s[0], &s[1], &s[2]);
- Exit_If_Error_On("Intersect");
- if ( Member(&s[2], lower) )
- Exit_If_Error_On("Member");
- else Exit_Indicating_Failed_Op("Member|Intersect");
- for ( i = lower+1; i <= upper; i++ )
- if ( Member(&s[2], i) )
- Exit_Indicating_Failed_Op("Member|Intersect");
- else Exit_If_Error_On("Member");
- }
-
- void Test_Subtraction_Operators(s, lower, upper)
- set s[];
- int lower, upper;
- {
- int i;
-
- Clear(&s[0]); /* Subtract one empty set */
- Clear(&s[1]); /* from another. */
- Subtract(&s[0], &s[1], &s[2]);
- Exit_If_Error_On("Subtract");
- for ( i = lower; i <= upper; i++ )
- if ( Member(&s[2], i) )
- Exit_Indicating_Failed_Op("Member|Subtract");
- else Exit_If_Error_On("Member");
- /*
- /* Added by Chris Fox to increase branch coverage
- */
- Insert(&s[0], lower); /* Test subtraction of two non- */
- Exit_If_Error_On("Insert"); /* non-empty, intersecting sets. */
- Insert(&s[0], lower+1); /* s2 <- {lower,lower+1}- */
- Exit_If_Error_On("Insert"); /* {lower,lower+2} */
- Clear(&s[1]);
- Insert(&s[1], lower);
- Exit_If_Error_On("Insert");
- Insert(&s[1], lower+2);
- Exit_If_Error_On("Insert");
- Subtract(&s[0], &s[1], &s[2]);
- Exit_If_Error_On("Intersect");
- if ( Member(&s[2], lower+1) )
- Exit_If_Error_On("Member");
- else Exit_Indicating_Failed_Op("Member|Subtract");
- if ( Member(&s[2], lower) )
- Exit_Indicating_Failed_Op("Member|Subtract");
- else Exit_If_Error_On("Member");
- for ( i = lower+2; i <= upper; i++ )
- if ( Member(&s[2], i) )
- Exit_Indicating_Failed_Op("Member|Intersect");
- else Exit_If_Error_On("Member");
-
- }
-
- void Test_Copy(s, lower, upper)
- set s[];
- int lower, upper;
- {
- int i;
-
- Clear(&s[0]); /* Create a set with every */
- for ( i = lower; i <= upper; i += 3 ) { /* third possible value, */
- Insert(&s[0], i); /* copy it, and make sure */
- Exit_If_Error_On("Insert"); /* both sets have the same */
- } /* members. */
-
- Copy(&s[0], &s[1]);
-
- for ( i = lower; i <= upper; i++ )
- if ( Member(&s[0], i) != Member(&s[1], i) )
- Exit_Indicating_Failed_Op("Member|Copy");
- else Exit_If_Error_On("Member");
- }
-
- int Count_Of_Elements_Iterated_Over;
-
- boolean Iterator(e)
- int e;
- {
- if ( e % 2 != 0 ) /* passed a value that wasn't inserted. */
- Exit_Indicating_Failed_Op("Iterate");
- Count_Of_Elements_Iterated_Over++;
- return TRUE;
- }
-
- void Test_Iterate(s, lower, upper)
- set s[];
- int lower, upper;
- {
- int i;
- int Count_Of_Elements_Added;
-
- Count_Of_Elements_Added = Count_Of_Elements_Iterated_Over = 0;
-
- Clear(&s[0]);
- for ( i = (lower/2)*2 + 2; i <= upper; i += 2 ) {
- Insert(&s[0], i); /* Insert all even values */
- Exit_If_Error_On("Insert"); /* (except perhaps the */
- Count_Of_Elements_Added++; /* first) into the set. */
- }
-
- Iterate(&s[0], Iterator);
- Exit_If_Error_On("Iterate");
- if ( Count_Of_Elements_Added != Count_Of_Elements_Iterated_Over )
- Exit_Indicating_Failed_Op("Iterate");
- }
-
- void Exit_If_Error_On(operation)
- char operation[];
- {
- if ( ! Error_Occurred() )
- return;
- printf("%s operation caused an error.\n", operation);
- exit(1);
- }
-
-
- void Exit_Indicating_Failed_Op(operation)
- char operation[];
- {
- printf("%s operation failed to function correctly.\n", operation);
- exit(1);
- }
-